package cn.ctyun.ipush.service.impl;

import cn.ctyun.ipush.dao.ScheduleJobDao;
import cn.ctyun.ipush.dao.TaskDao;
import cn.ctyun.ipush.model.*;
import cn.ctyun.ipush.service.ScheduleJobService;
import cn.ctyun.ipush.utils.DataUtils;
import cn.ctyun.ipush.utils.ScheduleUtils;
import cn.ctyun.ipush.vo.ScheduleJobVo;
import cn.ctyun.ipush.vo.TaskVo;
import com.dexcoder.commons.bean.BeanConverter;
import com.dexcoder.dal.JdbcDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 定时任务
 * <p/>
 * Created by liyd on 12/19/14.
 */
@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService {

    /**
     * 调度工厂Bean
     */
    @Autowired
    private Scheduler scheduler;

    /**
     * 通用dao
     */
    @Autowired
    private JdbcDao jdbcDao;

    @Autowired
    private ScheduleJobDao scheduleJobDao;

    @Autowired
    private TaskDao taskDao;


    /* 日志对象 */
    private final Logger LOG = LoggerFactory.getLogger(ScheduleJobServiceImpl.class);

    /**
     * wjf
     */
    @Transactional
    public void initScheduleJob() {
        List<TaskModel> taskModelList = taskDao.queryList();
        if (CollectionUtils.isEmpty(taskModelList)) {
            LOG.info("-----init job:  task list is null -------");
            return;
        }
        //set all  scheduleJob  to idDeleted
        scheduleJobDao.setAllJobIsDeleted();
        for (TaskModel taskModel : taskModelList) {
            TaskVo taskVo = taskDao.getTaskVoByTaskModel(taskModel);
            boolean isStart= taskDao.isStartTask(taskVo);
            if(!isStart){
                continue;
            }
            if (null != taskVo)
                if(taskVo.getTaskDetail().getTaskStatus().equals("1")){ // 0 待执行  1  执行中  2 暂停中  999 异常
                    scheduleJobDao.insert(taskVo);
                }
        }
    }

    /**
     * wjf
     *
     * @param taskVo
     * @return
     */
    public boolean insert(TaskVo taskVo) {
        return scheduleJobDao.insert(taskVo);
    }

    /**
     * wjf
     *
     * @param taskVo
     * @return
     */
    public boolean update(TaskVo taskVo) {

        //先删除运行中的job
        ScheduleUtils.deleteScheduleJob(scheduler, taskVo.getTaskDetail().getTaskName(), taskVo.getTaskDetail().getTaskGroupName());
        //删除sheduleJob,设置状态为isDeleted 1
        scheduleJobDao.setAllJobIsDeleted();
        //再创建，包括数据库记录和运行中的job
        insert(taskVo);
        return true;
    }


    /**
     * @param scheduleJobList
     */
    public void delete(List<ScheduleJob> scheduleJobList) {
        //删除运行的任务
        ScheduleUtils.deleteScheduleJob(scheduler, scheduleJobList.get(0).getJobName(), scheduleJobList.get(0).getJobGroup());
        //删除数据
        scheduleJobDao.setAllJobIsDeletedByTaskId(scheduleJobList.get(0).getTaskId());
    }

    public void delete(String taskId) {
        List<ScheduleJob> scheduleJobList = getScheduleJobListByTaskId(taskId);
        if(scheduleJobList.size()>0){
            delete(scheduleJobList);
        }
    }

    /**
     * 得到单个taskId对应的job list
     *
     * @param taskId
     * @return
     */
    public List<ScheduleJob> getScheduleJobListByTaskId(String taskId) {
        return scheduleJobDao.getScheduleJobList(taskId);
    }

    public void runOnce(String scheduleJobId) {
        ScheduleJob scheduleJob = scheduleJobDao.querySingleResult(scheduleJobId);
        ScheduleUtils.runOnce(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
    }

    public void runOnce(TaskDetailModel taskDetailModel) {
        ScheduleUtils.runOnce(scheduler, taskDetailModel.getTaskName(), taskDetailModel.getTaskGroupName());
    }

    public void pauseJob(String scheduleJobId) {
        ScheduleJob scheduleJob = scheduleJobDao.querySingleResult(scheduleJobId);
        scheduleJob.setStatus("暂停");
        //更新作业job
        ScheduleUtils.pauseJob(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
        //更新数据库
        scheduleJobDao.update(scheduleJob);
    }

    public void pauseTask(TaskDetailModel taskDetailModel, String taskId) {
        ScheduleJob scheduleJob = new ScheduleJob();
        scheduleJob.setStatus("暂停");
        //更新作业job
        ScheduleUtils.pauseJob(scheduler, taskDetailModel.getTaskName(), taskDetailModel.getTaskGroupName());
        //更新数据库
        scheduleJobDao.pauseTask(scheduleJob, taskId);
    }

    public void resumeJob(String scheduleJobId) {
        ScheduleJob scheduleJob = scheduleJobDao.querySingleResult(scheduleJobId);
        scheduleJob.setStatus("正常");
        ScheduleUtils.resumeJob(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
        //更新数据库
        scheduleJobDao.update(scheduleJob);
    }

    @Override
    public void resumeTask(TaskDetailModel taskDetailModel, String taskId) {
        ScheduleJob scheduleJob = new ScheduleJob();
        scheduleJob.setStatus("正常");
        ScheduleUtils.resumeJob(scheduler, taskDetailModel.getTaskName(), taskDetailModel.getTaskGroupName());
        //更新数据库
        scheduleJobDao.resumeTask(scheduleJob, taskId);
    }

    public List<ScheduleJobVo> queryList(ScheduleJobVo scheduleJobVo) {

        List<ScheduleJob> scheduleJobs = jdbcDao.queryList(scheduleJobVo.getTargetObject(ScheduleJob.class));

        List<ScheduleJobVo> scheduleJobVoList = BeanConverter.convert(ScheduleJobVo.class, scheduleJobs);
        try {
            for (ScheduleJobVo vo : scheduleJobVoList) {

                JobKey jobKey = ScheduleUtils.getJobKey(vo.getJobName(), vo.getJobGroup());
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                if (CollectionUtils.isEmpty(triggers)) {
                    continue;
                }

                //这里一个任务可以有多个触发器， 但是我们一个任务对应一个触发器，所以只取第一个即可，清晰明了
                Trigger trigger = triggers.iterator().next();
                scheduleJobVo.setJobTrigger(trigger.getKey().getName());

                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                vo.setStatus(triggerState.name());

                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    vo.setCronExpression(cronExpression);
                }
            }
        } catch (SchedulerException e) {
            //演示用，就不处理了
        }
        return scheduleJobVoList;
    }

    public List<ScheduleJobVo> queryExecutingJobList() {
        try {
            List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
            List<ScheduleJobVo> jobList = new ArrayList<ScheduleJobVo>(executingJobs.size());
            for (JobExecutionContext executingJob : executingJobs) {
                ScheduleJobVo job = new ScheduleJobVo();
                JobDetail jobDetail = executingJob.getJobDetail();
                JobKey jobKey = jobDetail.getKey();
                Trigger trigger = executingJob.getTrigger();
                job.setJobName(jobKey.getName());
                job.setJobGroup(jobKey.getGroup());
                job.setJobTrigger(trigger.getKey().getName());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                job.setStatus(triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    job.setCronExpression(cronExpression);
                }
                jobList.add(job);
            }
            return jobList;
        } catch (SchedulerException e) {
            //演示用，就不处理了
            return null;
        }

    }

    /**
     * 更新、删除参数信息时，
     *
     * @param dataSourceModel
     */
    @Override
    public void updateExeucteJobParamInfo(DataSourceModel dataSourceModel) {
        //jobKey
        TaskModel taskModel = new TaskModel();
        taskModel.setDataSourceId("e3779f86ab534a35ab72bfd31e155e37");
        TaskVo taskVo = taskDao.getTaskVoByTaskModel(taskModel);
        TaskDetailModel taskDetailModel = taskVo.getTaskDetail();
        String jobGroupName = taskDetailModel.getTaskGroupName();
        String jobName = taskDetailModel.getTaskName();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);

        try {
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            jobDetail.getJobDataMap().put("test", "test");
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }


    // 上面是新的，下面是旧的--------------------------------------------------------------------------


//    public Long insert(ScheduleJobVo scheduleJobVo) {
//        ScheduleJob scheduleJob = scheduleJobVo.getTargetObject(ScheduleJob.class);
//        ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
//        return jdbcDao.insert(scheduleJob);
//    }
//
//    public void update(ScheduleJobVo scheduleJobVo) {
//        ScheduleJob scheduleJob = scheduleJobVo.getTargetObject(ScheduleJob.class);
//        ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
//        jdbcDao.update(scheduleJob);
//    }
//
//    public void delUpdate(ScheduleJobVo scheduleJobVo) {
//        ScheduleJob scheduleJob = scheduleJobVo.getTargetObject(ScheduleJob.class);
//        //先删除
//        ScheduleUtils.deleteScheduleJob(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
//        //再创建
//        ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
//        //数据库直接更新即可
//        jdbcDao.update(scheduleJob);
//    }
//
//
//
//    public void delete(Long scheduleJobId) {
//        ScheduleJob scheduleJob = jdbcDao.get(ScheduleJob.class, scheduleJobId);
//        //删除运行的任务
//        ScheduleUtils.deleteScheduleJob(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
//        //删除数据
//        jdbcDao.delete(ScheduleJob.class, scheduleJobId);
//    }
//
//    public void runOnce(Long scheduleJobId) {
//
//        ScheduleJob scheduleJob = jdbcDao.get(ScheduleJob.class, scheduleJobId);
//        ScheduleUtils.runOnce(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
//    }
//
//
//
//    public void pauseJob(Long scheduleJobId) {
//
//        ScheduleJob scheduleJob = jdbcDao.get(ScheduleJob.class, scheduleJobId);
//        ScheduleUtils.pauseJob(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
//
//        //演示数据库就不更新了
//    }
//
//    public void resumeJob(Long scheduleJobId) {
//        ScheduleJob scheduleJob = jdbcDao.get(ScheduleJob.class, scheduleJobId);
//        ScheduleUtils.resumeJob(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
//
//        //演示数据库就不更新了
//    }
//
//
//
//    public ScheduleJobVo get(Long scheduleJobId) {
//        ScheduleJob scheduleJob = jdbcDao.get(ScheduleJob.class, scheduleJobId);
//        return scheduleJob.getTargetObject(ScheduleJobVo.class);
//    }
//
//    public ScheduleJobVo get(String scheduleJobId) {
//        return null;
//    }


}
